﻿namespace KLF.Lib.Browser.DOM
{
    #region Using Statements

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    #endregion

    public interface IStorage<T>
    {
        void clear();

        long length { get; }

        T getItem(string key);

        string key(int index);

        void removeItem(string key);

        void setItem(string key, T data);
    }

    /// <summary>
    /// This is a constructor (Storage) for all Storage instances 
    /// (sessionStorage and globalStorage[location.hostname]).  Setting
    /// Storage.prototype.removeKey = function(key)
    /// {
    ///     this.removeItem(this.key(key)) 
    /// }
    /// would be accessed as localStorage.removeKey and sessionStorage.removeKey.
    /// </summary>
    public class Storage<T> : IStorage<T>
    {
        #region Constructors

        internal Storage()
        {
            Items = new Dictionary<string, T>();
        }

        #endregion

        #region Attributes

        /// <summary>
        /// The internal storage dictionary
        /// </summary>
        protected Dictionary<string, T> Items { get; set; }

        #endregion

        #region IStorage Members

        /// <summary>
        /// Removes all data from the collection.
        /// </summary>
        public void clear()
        {
            Items.Clear();
        }

        /// <summary>
        /// The number of items in storage.
        /// </summary>
        public long length
        {
            get { return Items.Count; }
        }

        /// <summary>
        /// Returns a stored item by means of the associated key.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public T getItem(string key)
        {
            return Items.ContainsKey(key) ? Items[key] : default(T);
        }

        /// <summary>
        /// Returns the key name for a numbered index.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public string key(int index)
        {
            string[] keys = Items.Keys.ToArray();
            return index > -1 && index < keys.Length ? keys[index] : null;
        }

        /// <summary>
        /// Removes an item from storage.
        /// </summary>
        /// <param name="key"></param>
        public void removeItem(string key)
        {
            if (Items.ContainsKey(key))
            {
                Items.Remove(key);
            }
        }

        /// <summary>
        /// Stores an item in storage.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        public void setItem(string key, T data)
        {
            if (!String.IsNullOrEmpty(key))
            {
                Items[key] = data;
            }
        }

        #endregion
    }
}
